#ifndef CHATSERVICE_H
#define CHATSERVICE_H

#include <muduo/net/TcpConnection.h>
#include <unordered_map>
#include <functional>
#include <mutex>

#include "redis.hpp"
#include "json.hpp"
#include "public.hpp"
#include "usermodel.hpp"
#include "offlinemsgmodel.hpp"
#include "FriendModel.hpp"
#include "groupmodel.hpp"

using json = nlohmann::json;
using MsHandler = std::function<void(const muduo::net:: TcpConnectionPtr& conn, json& js, muduo::Timestamp)>;
// 注册单例设计模式
class ChatService
{
public:
    static ChatService* Instance();
    ~ChatService();
    MsHandler GetHandler(EnMsHandler msgId);
    void Reset();
    // 处理用户异常退出的情况
    void ClinetCloseException(const muduo::net::TcpConnectionPtr& conn);
private:
    void LoginHandler(const muduo::net:: TcpConnectionPtr& conn, json& js, muduo::Timestamp);
    void RegisterHandler(const muduo::net:: TcpConnectionPtr& conn, json& js, muduo::Timestamp);
    
    // 一对一聊天
    void OnChatHandler(const muduo::net::TcpConnectionPtr& conn, json& js, muduo::Timestamp);
    // 添加好友
    void AddFriendHanlder(const muduo::net::TcpConnectionPtr& conn, json& js, muduo::Timestamp);
    // 群组
    void CreateGroup(const muduo::net::TcpConnectionPtr& conn, json& js, muduo::Timestamp);
    void AddGroup (const muduo::net::TcpConnectionPtr& conn, json& js, muduo::Timestamp);
    void ChatGroup (const muduo::net::TcpConnectionPtr& conn, json& js, muduo::Timestamp);
    void Loginout(const muduo::net::TcpConnectionPtr& conn, json& js, muduo::Timestamp);

    void SubscribeHandler(int, std::string);
private:
    ChatService();
    // 根据不同的枚举类型，产生不同的回调函数
    std::unordered_map<EnMsHandler, MsHandler> handlers;
    std::unordered_map<int, muduo::net::TcpConnectionPtr> conns;

    // 互斥锁，保证线程安全
    std::mutex mtx;
    UserModel userModel;
    OfflineMsgModel offlineMsgModel;
    FriendModel friendModel;
    GroupModel groupModel;
    // redis
    Redis _redis;
};

#endif